package com.CST.controller.zx;

import com.CST.common.api.ResultObject;
import com.CST.dto.zx.ProSelDTO;
import com.CST.dto.zx.ProjectDTO;
import com.CST.entity.cb.BdDepartment;
import com.CST.entity.cb.BdSysUser;
import com.CST.entity.zx.ZXAllocation;
import com.CST.entity.zx.ZX_Project;
import com.CST.entity.zx.ZxViewPerson;
import com.CST.mapper.cst.zx.ZX_ViewPersonMapper;
import com.CST.service.cb.IBdDepartmentService;
import com.CST.service.cb.IBdSysUserService;
import com.CST.service.zx.*;
import com.CST.util.ExcelTransfer;
import com.CST.util.PageHelperTool;
import com.CST.vo.cb.BdDepartmentVO;
import com.CST.vo.cb.BdSysUserDeptCodeVO;
import com.CST.vo.cb.SysUserDeptVo;
import com.CST.vo.zx.EntryVo;
import com.CST.vo.zx.ProjectTemplateVo;
import com.CST.vo.zx.ProjectVo;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Api(tags = "项目信息管理")
public class ZX_ProjectInfoController {

    @Autowired
    IZX_ProjectInfoService zxProjectInfoService;

    @Autowired
    IBdDepartmentService departmentService;
    @Autowired
    IZxDataentryService dataentryService;

    @Autowired
    IZxFinancialService zxFinancialService;
    @Autowired
    IZX_LogService zxLogService;
    @Autowired
    IZX_AuditService zxAuditService;
    @Autowired
    IBdSysUserService userService;

    @Autowired
    IZX_AllocationService allocationService;

    @Autowired
    IZX_ViewPersonService viewPersonService;


    /**
     * @描述 查询项目信息
     * @参数
     * @创建人 ellen
     * @创建时间 2023-03-07 11:08
     */
    @PostMapping("/sync")
    @ApiOperation(value = "列表查询项目信息")
    @ApiImplicitParams({
            //参数效验
            @ApiImplicitParam(name = "pageSize", value = "每页大小", required = true),
            @ApiImplicitParam(name = "pageNum", value = "页编号", required = true),
            @ApiImplicitParam(name = "financialCode", value = "财务编码分类查询", required = false),
            @ApiImplicitParam(name = "projectCode", value = "项目编码分类查询", required = false),
            @ApiImplicitParam(name = "leaderName", value = "负责人姓名分类查询", required = false),
            @ApiImplicitParam(name = "projectName", value = "项目简称/全称", required = false),

    })
    public ResultObject<PageInfo<ProjectVo>> syncProject(@RequestBody ProSelDTO proSelDTO) throws Exception {
        List<ProjectVo> projectVoList = zxProjectInfoService.getProjectVos(proSelDTO);

        PageInfo<ProjectVo> projectBoPageInfo = PageHelperTool.excutePageInfo(projectVoList, proSelDTO.getPageNum(), proSelDTO.getPageSize());
        return ResultObject.success(projectBoPageInfo);
    }

    @GetMapping("/getProjectDetail")
    @ApiOperation(value = "查看项目详情")
    public ResultObject<ProjectVo> getProjectDetail(String financialCode) throws ParseException {
        ProjectVo projectDetail = zxProjectInfoService.getProjectDetail(financialCode);
        return ResultObject.success(projectDetail);
    }

    @GetMapping("/project_type")
    @ApiOperation("项目类型")
    public ResultObject<List<EntryVo>> getProjectType(@RequestParam String type, HttpServletRequest request) {
        List<EntryVo> entryVoList = zxProjectInfoService.getProjectType(type, request);
        return ResultObject.success(entryVoList);
    }

    @GetMapping("/project_leaderAndDept")
    @ApiOperation("获取项目领导人")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "用户真实姓名，搜索下拉")
    })
    public ResultObject<List<SysUserDeptVo>> getProjectLeader(@RequestParam String name) {
        List<BdSysUser> user = userService.getUsers(name, "");

        List<SysUserDeptVo> list = new ArrayList<>();
        user.forEach(t -> {
            SysUserDeptVo v = new SysUserDeptVo();
            v.setUser(t);
            BdDepartmentVO dvo = new BdDepartmentVO();
            List<BdSysUserDeptCodeVO> parent = zxProjectInfoService.getDeptByRootCode(t.getDeptCode());
            if (parent.size() >= 1) {
                dvo.setDeptCode(parent.get(0).getDeptCode());
                dvo.setDeptCode(parent.get(0).getDeptName());
                if (parent.get(0).getDeptCode().equals(t.getDeptCode())) {
                    v.setIdx(0L);
                }
                parent.remove(0);
            }
            if (parent.size() > 0) {
                for (int i = 0; i < parent.size(); i++) {
                    if (t.getDeptCode().equals(parent.get(i).getDeptCode())) {
                        v.setIdx(Long.valueOf(i));
                    }
                }
            }
            dvo.setChildrens(parent);
            v.setDepartment(dvo);
            list.add(v);
        });
        return ResultObject.success(list);
    }


    @GetMapping("/project_root_dept")
    @ApiOperation("科室信息")
    public ResultObject getRootDept() {
        List<BdDepartment> deptList = zxProjectInfoService.getRootDept();
        return ResultObject.success(deptList);
    }

    @GetMapping("/get_leader")
    @ApiOperation(value = "获取项目负责人")
    public ResultObject<List<BdSysUser>> getLeader(String userName) {
        List<BdSysUser> leaders = zxProjectInfoService.getLeader(userName);
        if (userName.isEmpty()) {
            return ResultObject.success(leaders.subList(0, 20));
        }
        return ResultObject.success(leaders);
    }


    @PostMapping("/download_ex")
    @ApiOperation("下载模板文件，必要参数HttpServletResponse response,")
    public void download(HttpServletResponse response) throws Exception {
        ExcelTransfer<ProjectTemplateVo> excelTransfer = new ExcelTransfer<>();
        try {
            // excelTransfer.exportExcel(response,null,"项目信息模板","项目信息", ProjectTemplateVo.class);

            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = "dict";
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");

            //调用方法进行写操作

            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            //获取sheet0对象
            WriteSheet mainSheet = EasyExcel.writerSheet(0, "项目信息").head(ProjectTemplateVo.class).build();
            excelWriter.write(new ArrayList<>(), mainSheet);

            //获取sheet1对象
            WriteSheet detailSheet = EasyExcel.writerSheet(1, "分批配置经费").head(ZXAllocation.class).build();
            excelWriter.write(new ArrayList<>(), detailSheet);

            //关闭流
            excelWriter.finish();
        } catch (Exception e) {
            throw new Exception("下载失败");
        }
    }

    @PostMapping("/download")
    @ApiOperation("下载文件，必要参数HttpServletResponse response,")
    @ApiImplicitParams({
            //参数效验
            @ApiImplicitParam(name = "financialCode", value = "财务编码分类查询", required = false),
            @ApiImplicitParam(name = "projectCode", value = "项目编码分类查询", required = false),
            @ApiImplicitParam(name = "leaderName", value = "负责人姓名分类查询", required = false),
            @ApiImplicitParam(name = "financialName", value = "项目简称", required = false),
            @ApiImplicitParam(name = "projectInfo", value = "项目全称", required = false)
    })
    public void downloadFile(@RequestBody ProSelDTO proSelDTO, HttpServletResponse response) throws Exception {
        zxProjectInfoService.downloadFile(proSelDTO, response);
    }


    @PostMapping("/import")
    @ApiOperation("导入文件")
    public ResultObject importProject(MultipartFile file) throws IOException {
        zxProjectInfoService.importProject(file);
        return ResultObject.success("导入成功");
    }

    @PostMapping("/importAllocation")
    @ApiOperation("导入分批经费")
    public ResultObject importAllocation(MultipartFile file) {
        allocationService.importAllocation(file);
        //获取所有分批经费的财务编号,更新主表中的总金额


        return ResultObject.success("导入成功");
    }


    /**
     * @描述 用户编辑项目信息, 项目存在就修改, 不存在就新增到本地库
     * @参数 projectDTO
     * @返回值
     * @创建人 ellen
     * @创建时间 2023-03-07 11:28
     */
    @PostMapping("/update_project")
    @ApiOperation("编辑项目信息")
    @Transactional(rollbackFor = Exception.class)
    public ResultObject updateProjectInfo(@RequestBody ProjectDTO projectDTO) throws Exception {
        if (StringUtils.isEmpty(projectDTO.getFinancialCode())) {
            return ResultObject.failed("财务编码不能为空");
        }
        if (StringUtils.isEmpty(projectDTO.getProjectCode())) {
            return ResultObject.failed("项目编号不能为空");
        }

        if (projectDTO.getEntryId() == null || projectDTO.getEntryName() == null) {
            return ResultObject.failed("项目类别不能为空");
        }

        if (StringUtils.isEmpty(projectDTO.getFinancialName())) {
            return ResultObject.failed("项目简称不能为空");
        }
        if (StringUtils.isEmpty(projectDTO.getProjectInfo())) {
            return ResultObject.failed("项目全称不能为空");
        }

        if (StringUtils.isEmpty(projectDTO.getUserId()) || StringUtils.isEmpty(projectDTO.getUserName())) {
            return ResultObject.failed("项目负责人不能为空");
        }

        if (projectDTO.getIncome() == null) {
            projectDTO.setIncome(BigDecimal.ZERO);
        }
        Integer count = zxProjectInfoService.isExistsRelationByFinancialCode(projectDTO.getFinancialCode());
        if (count <= 0) {
            ZX_Project projectInfo = new ZX_Project();

            BeanUtils.copyProperties(projectDTO, projectInfo);
            //默认字段
            projectInfo.setIsDelete(0);
            projectInfo.setCreateTime(LocalDateTime.now());
            projectInfo.setUpdateTime(LocalDateTime.now());
            //插入
            zxProjectInfoService.addProject(projectInfo);
            if (projectDTO.getAllocations() != null && projectDTO.getAllocations().size() > 0) {
                //先删除
                allocationService.deleteByFinancialCode(projectInfo.getFinancialCode());
                //后插入
                allocationService.insertBatchZxAllocation(projectDTO.getAllocations());
            }
        } else {
            //修改
            zxProjectInfoService.updateProjectInfo(projectDTO);
            if (projectDTO.getAllocations() != null && projectDTO.getAllocations().size() > 0) {
                //先删除
                allocationService.deleteByFinancialCode(projectDTO.getFinancialCode());
                //后插入
                allocationService.insertBatchZxAllocation(projectDTO.getAllocations());
            }
        }

        //可查看人 先删除后插入
        viewPersonService.deleteByFinancialCode(projectDTO.getFinancialCode());
        if (CollectionUtils.isNotEmpty(projectDTO.getViewPersons())) {
            List<String> collect = projectDTO.getViewPersons().stream().map(t -> t.getUserName()).collect(Collectors.toList());
            List<BdSysUser> selectUser = userService.getSelectUser(collect);
            projectDTO.getViewPersons().forEach(item -> {
                BdSysUser matchSysUser = selectUser.stream().filter(t -> t.getUserName().equals(item.getUserName())).findFirst().orElse(null);
                item.setRealName(matchSysUser == null ? "" : matchSysUser.getRealName());
            });
            viewPersonService.insertBatchZxViewPerson(projectDTO.getViewPersons());
        }

        return ResultObject.success("操作成功");
    }

    /**
     * @描述 删除项目信息
     * @参数 财务编码删除项目信息
     * @返回值
     * @创建人 ellen
     * @创建时间 2023-03-08 10:36
     */
    @Transactional(rollbackFor = Exception.class)
    @DeleteMapping("/delete_project")
    @ApiOperation("删除项目")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "财务编码唯一主键，删除项目,需要登录用户")
    })
    public ResultObject deleteProjectByUser(@RequestParam("code") String financial_code, HttpServletRequest request) {
        //从请求从获取userId
        String userId = request.getHeader("userId");
        zxProjectInfoService.deleteProjectByUser(userId, financial_code);
        return ResultObject.successMsgReturn("操作成功");
    }

    @GetMapping("/collectFinancialData")
    @ApiOperation("采集财务编号/项目简称数据")
    public ResultObject collectFinancialData() {
        LocalDateTime lt = LocalDateTime.now();
        zxFinancialService.collectFinancialData();
        return ResultObject.success(lt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }
}
